#include "snake_controller.h"

SnakeController::SnakeController()
{
    // 构造函数
}

SnakeController::~SnakeController()
{
    // 析构函数
}

bool SnakeController::handlePlayer1Input(int key, Snake *snake1, bool &boost1,
                                         std::vector<TemporaryObstacle> &temporaryObstacles, int skillCooldownFrames,
                                         long long frameCounter, long long &player1LastDropFrame, bool &isSkillActive1)
{
    // Player 1 controls (WASD)
    switch (key)
    {
    case 'w':
    case 'W':
        if (snake1->getCurrentDirection() == Direction::Up)
        {
            boost1 = !boost1;
        }
        else
        {
            boost1 = false;
        }
        return snake1->changeDirection(Direction::Up);
        break;
    case 's':
    case 'S':
        if (snake1->getCurrentDirection() == Direction::Down)
        {
            boost1 = !boost1;
        }
        else
        {
            boost1 = false;
        }
        return snake1->changeDirection(Direction::Down);
        break;
    case 'a':
    case 'A':
        if (snake1->getCurrentDirection() == Direction::Left)
        {
            boost1 = !boost1;
        }
        else
        {
            boost1 = false;
        }
        return snake1->changeDirection(Direction::Left);
        break;
    case 'd':
    case 'D':
        if (snake1->getCurrentDirection() == Direction::Right)
        {
            boost1 = !boost1;
        }
        else
        {
            boost1 = false;
        }
        return snake1->changeDirection(Direction::Right);
        break;
    case 'e':
    case 'E':
        // Player 1 uses skill to drop tail
        // 检查冷却时间
        if ((frameCounter >= player1LastDropFrame + skillCooldownFrames) && !isSkillActive1)
        {
            isSkillActive1 = true;
            player1LastDropFrame = frameCounter;
        } 
        else if (isSkillActive1)
        {
            isSkillActive1 = false;
        }
        return false;
        break;
    default:
        return false;
    }
}

bool SnakeController::handlePlayer2Input(int key, Snake *snake2, bool &boost2,
                                         std::vector<TemporaryObstacle> &temporaryObstacles, int skillCooldownFrames,
                                         long long frameCounter, long long &player2LastDropFrame, bool &isSkillActive2)
{
    // Player 2 controls (IJKL)
    switch (key)
    {
    case 'i':
    case 'I':
        if (snake2->getCurrentDirection() == Direction::Up)
        {
            boost2 = !boost2;
        }
        else
        {
            boost2 = false;
        }
        return snake2->changeDirection(Direction::Up);
        break;
    case 'k':
    case 'K':
        if (snake2->getCurrentDirection() == Direction::Down)
        {
            boost2 = !boost2;
        }
        else
        {
            boost2 = false;
        }
        return snake2->changeDirection(Direction::Down);
        break;
    case 'j':
    case 'J':
        if (snake2->getCurrentDirection() == Direction::Left)
        {
            boost2 = !boost2;
        }
        else
        {
            boost2 = false;
        }
        return snake2->changeDirection(Direction::Left);
        break;
    case 'l':
    case 'L':
        if (snake2->getCurrentDirection() == Direction::Right)
        {
            boost2 = !boost2;
        }
        else
        {
            boost2 = false;
        }
        return snake2->changeDirection(Direction::Right);
        break;
    case 'o':
    case 'O':
        // Player 2 uses skill to drop tail
        // 检查冷却时间
        if ((frameCounter >= player2LastDropFrame + skillCooldownFrames) && !isSkillActive2)
        {
            isSkillActive2 = true;
            player2LastDropFrame = frameCounter;
        } 
        else if (isSkillActive2)
        {
            isSkillActive2 = false;
        }
        return false;
        break;
    default:
        return false;
    }
}

bool SnakeController::handlePlayer1InputReversed(int key, Snake *snake1, bool &boost1,
                                                 std::vector<TemporaryObstacle> &temporaryObstacles, int skillCooldownFrames,
                                                 long long frameCounter, long long &player1LastDropFrame, bool &isSkillActive1)
{
    switch (key)
    {
    case 'w':
    case 'W':
        // 反向：上键变下
        if (snake1->getCurrentDirection() == Direction::Down)
        {
            boost1 = !boost1;
        }
        else
        {
            boost1 = false;
        }
        return snake1->changeDirection(Direction::Down);
        break;
    case 's':
    case 'S':
        // 反向：下键变上
        if (snake1->getCurrentDirection() == Direction::Up)
        {
            boost1 = !boost1;
        }
        else
        {
            boost1 = false;
        }
        return snake1->changeDirection(Direction::Up);
        break;
    case 'a':
    case 'A':
        // 反向：左键变右
        if (snake1->getCurrentDirection() == Direction::Right)
        {
            boost1 = !boost1;
        }
        else
        {
            boost1 = false;
        }
        return snake1->changeDirection(Direction::Right);
        break;
    case 'd':
    case 'D':
        // 反向：右键变左
        if (snake1->getCurrentDirection() == Direction::Left)
        {
            boost1 = !boost1;
        }
        else
        {
            boost1 = false;
        }
        return snake1->changeDirection(Direction::Left);
        break;
    case 'e':
    case 'E':
        // 技能在反向状态下仍然可用
        if ((frameCounter >= player1LastDropFrame + skillCooldownFrames) && !isSkillActive1)
        {
            isSkillActive1 = true;
            player1LastDropFrame = frameCounter;
        }
        else if (isSkillActive1)
        {
            isSkillActive1 = false;
        }
        return false;
        break;
    default:    
        return false;
    }
}

bool SnakeController::handlePlayer2InputReversed(int key, Snake *snake2, bool &boost2,
                                                 std::vector<TemporaryObstacle> &temporaryObstacles, int skillCooldownFrames, // Add skillCooldownFrames as an argumen
                                                 long long frameCounter, long long &player2LastDropFrame, bool &isSkillActive2)
{
    switch (key)
    {
    case 'i':
    case 'I':
        // 反向：上键变下
        if (snake2->getCurrentDirection() == Direction::Down)
        {
            boost2 = !boost2;
        }
        else
        {
            boost2 = false;
        }
        return snake2->changeDirection(Direction::Down);
        break;
    case 'k':
    case 'K':
        // 反向：下键变上
        if (snake2->getCurrentDirection() == Direction::Up)
        {
            boost2 = !boost2;
        }
        else
        {
            boost2 = false;
        }
        return snake2->changeDirection(Direction::Up);
        break;
    case 'j':
    case 'J':
        // 反向：左键变右
        if (snake2->getCurrentDirection() == Direction::Right)
        {
            boost2 = !boost2;
        }
        else
        {
            boost2 = false;
        }
        return snake2->changeDirection(Direction::Right);
        break;
    case 'l':
    case 'L':
        // 反向：右键变左
        if (snake2->getCurrentDirection() == Direction::Left)
        {
            boost2 = !boost2;
        }
        else
        {
            boost2 = false;
        }
        return snake2->changeDirection(Direction::Left);
        break;
    case 'o':
    case 'O':
        // 技能在反向状态下仍然可用
        if ((frameCounter >= player2LastDropFrame + skillCooldownFrames) && !isSkillActive2)
        {
            isSkillActive2 = true;
            player2LastDropFrame = frameCounter;
        }
        else if (isSkillActive2)
        {
            isSkillActive2 = false;
        }
        return false;
        break;
    default:
        return false;
    }
}

// 新增：支持暂停的控制方法
int SnakeController::controlSnakesWithPause(Snake* snake1, Snake* snake2, bool& boost1, bool& boost2,
                                            std::vector<TemporaryObstacle>& temporaryObstacles,
                                            long long frameCounter, long long& player1LastDropFrame, int skillCooldownFrames,
                                            long long& player2LastDropFrame, bool& isPaused, 
                                            bool isReversed1, bool isReversed2, bool *isSkillActive1, bool *isSkillActive2)
{
    int key;
    bool player1TurnedThisFrame = false;
    bool player2TurnedThisFrame = false;
    int result = 0;  // 0=继续, 1=暂停切换, 2=退出请求

    while ((key = getch()) != ERR)
    {
        // 检查是否按下暂停键
        if (key == 'p' || key == 'P')
        {
            isPaused = !isPaused;
            result = 1;  // 暂停状态切换
            continue;
        }
        
        // 如果游戏已暂停，检查是否按下退出键
        if (isPaused)
        {
            if (key == 'q' || key == 'Q')
            {
                return 2;  // 请求退出游戏
            }
            continue;
        }

        // Player 1 input handling
        if (!player1TurnedThisFrame)
        {
            if (isReversed1)
            {
                if (handlePlayer1InputReversed(key, snake1, boost1, temporaryObstacles, skillCooldownFrames, frameCounter, player1LastDropFrame, *isSkillActive1))
                {
                    player1TurnedThisFrame = true;
                }
            }
            else
            {
                if (handlePlayer1Input(key, snake1, boost1, temporaryObstacles, skillCooldownFrames, frameCounter, player1LastDropFrame, *isSkillActive1))
                {
                    player1TurnedThisFrame = true;
                }
            }
        }

        // Player 2 input handling
        if (!player2TurnedThisFrame)
        {
            if (isReversed2)
            {
                if (handlePlayer2InputReversed(key, snake2, boost2, temporaryObstacles, skillCooldownFrames, frameCounter,player2LastDropFrame, *isSkillActive2))
                {
                    player2TurnedThisFrame = true;
                }
            }
            else
            {
                if (handlePlayer2Input(key, snake2, boost2, temporaryObstacles, skillCooldownFrames, frameCounter, player2LastDropFrame, *isSkillActive2))
                {
                    player2TurnedThisFrame = true;
                }
            }
        }
    }
    
    return result;
}